package tk.mynoteapp.dev.demo21.templatemethod.right;

import tk.mynoteapp.dev.demo21.templatemethod.Cart;
import tk.mynoteapp.dev.demo21.templatemethod.Db;
import tk.mynoteapp.dev.demo21.templatemethod.Item;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class AbstractCart {

    // 处理商品优惠的逻辑留给子类实现
    abstract void processCouponPrice(long userId, Item item);
    // 处理配送费的逻辑留给子类实现
    abstract void processDeliveryPrice(long userId, Item item);

    // 处理购物车的大量重复逻辑在父类实现
    public Cart process(long userId, Map<Long, Integer> items) {
        Cart cart = new Cart();

        //把Map的购物车转化为Item列表
        List<Item> itemList = new ArrayList<>();
        items.entrySet().stream().forEach(entry -> {
            Item item = new Item();
            item.setId(entry.getKey());
            item.setPrice(Db.getItemPrice(entry.getKey()));
            item.setQuantity(entry.getValue());
            itemList.add(item);
        });
        cart.setItems(itemList);

        // 处理运费和商品优惠
        // 通过模板方法模式，抽离出计算运费和商品优惠的代码，交由子类进行处理，客户端可以自由选择子类来实现不同的运费和优惠计算
        itemList.stream().forEach(item -> {
            processDeliveryPrice(userId, item);
            processCouponPrice(userId, item);
        });

        // 计算纯商品价格
        cart.setTotalItemPrice(cart.getItems().stream().map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()))).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 计算运费总价
        cart.setTotalDeliveryPrice(cart.getItems().stream().map(Item::getDeliveryPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 计算总优惠
        cart.setTotalDiscount(cart.getItems().stream().map(Item::getCouponPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 应付总价=商品总价+运费总价-总优惠
        cart.setPayPrice(cart.getTotalItemPrice().add(cart.getTotalDeliveryPrice()).subtract(cart.getTotalDiscount()));
        return cart;
    }

}
